home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-03 | 5.3 KB | 194 lines | [TEXT/R*ch] |
- (* Misc.sml *)
-
- fun (g o f) x = g (f x);
- fun a before (b: unit) = a;
-
- exception Option; (* belongs in General *)
-
- fun getOpt (SOME v, _) = v
- | getOpt (NONE, a) = a;
-
- fun isSome (SOME _) = true
- | isSome NONE = false;
-
- fun valOf (SOME v) = v
- | valOf NONE = raise Option;
-
- (* The definitions below implement the requirement that units
- Char, String and List are partially opened in the initial environment.
- *)
-
- val chr = Char.chr;
- val ord = Char.ord;
-
- val explode = String.explode;
- val implode = String.implode;
- val concat = String.concat;
- val str = String.str;
-
- exception Empty = List.Empty;
- val op @ = List.@;
- val app = List.app;
- val foldl = List.foldl;
- val foldr = List.foldr;
- val hd = List.hd;
- val length = List.length;
- val map = List.map;
- val null = List.null;
- val rev = List.rev;
- val tl = List.tl;
-
- val vector = Vector.fromList;
-
- (* Help -- a simple Moscow ML library browser, PS 1995-04-30
-
- Uses argv_ to get the library directory, then reads and displays
- (signature) files from that directory.
-
- The search facility cyclically searches for occurrences of a given
- string, and displays the line in which the string was found, as close
- to the center of the display (or portion displayed) as possible.
-
- Could use Config.normalizedUnitName to show the proper unit names
- under DOS, but that would create a dependency on the compiler structures.
-
- *)
-
- #ifdef macintosh
- val slash = #":"
- #else (* DOS/UNIX *)
- val slash = #"/"
- #endif
-
- local
- open BasicIO
- fun min (x, y) = if x < y then x else y : int;
- fun max (x, y) = if x < y then y else x : int;
-
- fun getstdlib () =
- let open Vector
- prim_val argv_ : string vector = 0 "command_line";
- val stop = length argv_ - 1;
- fun h i =
- if i < stop then
- if sub(argv_, i) = "-stdlib" then sub(argv_, i+1)
- else h (i+1)
- else
- raise Fail "Cannot find the standard libraries!"
- in h 0 end;
-
- fun show name (strs : string Vector.vector) =
- let prim_val sub_ : string -> int -> char = 2 "get_nth_char";
- val lines = Vector.length strs
- val sought = ref NONE
- fun instr s str =
- let val len = String.size s
- fun eq j k =
- j >= len orelse
- sub_ s j = Char.toLower (sub_ str k) andalso eq (j+1) (k+1)
- val stop = String.size str - len
- fun cmp k = k<=stop andalso (eq 0 k orelse cmp(k+1))
- in cmp 0 end;
- fun occurshere str =
- case !sought of
- NONE => false
- | SOME s => instr s str
- fun findline s curr =
- let fun h i =
- if i >= lines then NONE
- else if instr s (Vector.sub(strs, (i+curr) rem lines)) then
- SOME ((i + curr) rem lines)
- else h(i+1)
- in h 0 end
- val portion = 23
- fun wait next =
- let val prompt =
- "---- " ^ name ^ "[" ^
- makestring(floor(100.0 * real next / real lines))
- ^ "%]: down, up, bottom, top, /(find), next, quit: "
- fun toend () = (say "\n....\n";
- nextpart (lines - portion) portion)
- fun tobeg () = (say "\n....\n"; nextpart 0 portion)
- fun up () = (say "\n....\n";
- nextpart (next-3*portion div 2) portion)
- fun down () = if next=lines then toend()
- else nextpart next (portion div 2)
- fun find s =
- case findline s next of
- NONE =>
- (say ("**** String \"" ^ s ^ "\" not found\n");
- wait next)
- | SOME line =>
- (say "\n....\n";
- nextpart (line - portion div 2) portion)
- fun search chars =
- let fun stripnl [] = []
- | stripnl (#"\n" :: _) = []
- | stripnl (c :: cr) = Char.toLower c :: stripnl cr
- val s = implode (stripnl chars)
- in sought := SOME s; find s end
- fun findnext () =
- (case !sought of
- NONE => (say "**** No previous search string\n";
- wait next)
- | SOME s => find s)
- in
- say prompt;
- case explode(input_line std_in) of
- [] => ()
- | #"q" :: _ => ()
- | #"u" :: _ => up ()
- | #"d" :: _ => down ()
- | #"t" :: _ => tobeg ()
- | #"g" :: _ => tobeg ()
- | #"b" :: _ => toend ()
- | #"G" :: _ => toend ()
- | #"/" :: s => search s
- | #"n" :: s => findnext ()
- | _ => if next=lines then toend ()
- else nextpart next portion
- end
- and nextpart first amount =
- let val start = min(lines, max(first, 0))
- val stop = min(start + amount, lines)
- in prt wait start stop end
- and prt wait i stop =
- if i >= stop then wait i
- else
- let val line = Vector.sub(strs, i)
- in
- if occurshere line then say "@>" else say "+ ";
- say line;
- prt wait (i+1) stop
- end
- in
- say "\n";
- if lines <= portion then prt ignore 0 lines
- else nextpart 0 portion
- end
-
- fun readfile file =
- let fun extnd dir =
- (if String.size dir > 0
- andalso String.sub(dir, String.size dir - 1) = slash
- then dir
- else dir ^ String.str slash) ^ file
- val is = open_in_bin (extnd (getstdlib ()))
- fun h () = if end_of_stream is then []
- else input_line is :: h ()
- in Vector.fromList (h ()) end;
- in
- fun help "" =
- show "help"
- #["Moscow ML library browser: \n",
- "\n",
- " help \"lib\"; gives an overview of the library units\n",
- " help \"U\"; provides help on library unit U\n",
- "\n"]
- | help "lib" = show "Overview" (readfile "README")
- | help "README" = show "README" (readfile "README")
- | help unit =
- show unit (readfile (unit ^ ".sig"))
- handle Io _ => say "\nUnknown unit. Try:\n\n help \"\";\n\n"
- end
-